
/********************************************************************

    My simple calculator.

    Header file of My simple calculator.

********************************************************************/



/********************************************

    Class Variables

********************************************/

//-------------------------------------------

// Variables - class for saving user-defined variables.
// v - char in class Calculatortoken for th marking of variable.
class Variables{
public:
    string name;
    double value;
};

//-------------------------------------------



/********************************************

    Class Symbol_table

********************************************/

//-------------------------------------------

//
class Symbol_table{
private:
public:
    vector<Variables> var_table;

    void   variable_info();
    void   var_table_intial_value();
    void   var_table_push_back( const string&, double );
    void   var_table_push_back( const string& );

    double get_variable_value(  const string& );
    double set_variable_value(  const string& );
    double set_variable_value(  const string&, double );
    void   var_table_cout();

    Symbol_table(  ) { }
    //Symbol_table( vector<Variables> &t ) :var_table{ t } { }

};

//-------------------------------------------



/********************************************

    Class Calculatortoken

********************************************/

//-------------------------------------------

// The main class data in the calculator
class Calculatortoken {
public:
    char   kind;                    // what kind of token
    double value;                   // for numbers: a value
    string name;                    // string name this variable

    // Class constructors to initialize class different properties
    Calculatortoken( char ch )              :kind{ch}             { }
    Calculatortoken( char ch, double val )  :kind{ch}, value{val} { }
    Calculatortoken( char ch, string str )  :kind{ch}, name{str}  { }
    Calculatortoken( char ch, double val, string str )
                                            :kind{ch}, value{val}, name{str} { }
};



/********************************************

    Class Calculator

********************************************/

//-------------------------------------------

// The main class in this calculator
class Calculator{
public:
    void welcome();
    void get();
    void get( string& );
    void out();
    void cleardate();
    double result = 0;

    Calculator(  ) { }
    Calculator( string &s ) :str{s} { }
private:
    string str              = " ";
    string str_part         = " ";
    const  char number      = '8';// '8' - it's char is number
    Calculatortoken t{' ',0," "};
    vector<Calculatortoken> tok;
    Symbol_table vars;
    const  char variable    = 'v';// 'v' - it's char is variables number
    bool   nocalculation    = false;
    int    tok_begin_minus  = 0;
    int    tok_before_minus = 0;

    void char_plus(              int );
    void char_minus(             int );
    void char_minus(             int, int&, vector<int>&, bool& );
    void char_multiply(          int );
    void char_divide(            int );
    void char_percent(           int );
    void char_exclamation(       int );
    void char_roundbrace_open(   int, int& );
    void char_roundbrace_close(  int, int&, int&, vector<int>& );
    void char_figurebrace_open(  int, int& );
    void char_figurebrace_close( int, int&, int&, int&, bool&, vector<int>& );
    void brace_definition(       char,vector<char>& );
    int  brace_search(           int, char );
    void char_separator(         int );
    void char_point();
    void char_number(            int );

    void   strexpression(        string&, Calculatortoken&, vector<Calculatortoken>& );
    double strnum();
    double strnum_offset(        double, int, int, bool, int );
    void   putintoken(           Calculatortoken&, vector<Calculatortoken>&, char );
    void   putintoken(           Calculatortoken&, vector<Calculatortoken>&, char, double );
    tokenerase();
    tokeneraseafteroperation(    int&,  int, int, int&, int& );
    double calculation();
    double calcoperation(        double, bool& );
    double calcoperationinbrace( double, char, char );
    bool   num_or_var( int );
    bool   num_or_var( int, int );
    bool   num_or_var( int, int, int );
    bool   braceconverce( char );
    double multiplication_and_division(  double );
    double multiplication_and_division(  double, int&, int& );
    double addition_and_subtraction(     double );
    double addition_and_subtraction(     double, int&, int& );
    double factorial( double );
    double factorial( double, int&, int& );

    bool   variable_or_number();
    void   char_letter(   int );
    void   char_equal(    int );
    double equals(        double );
    double variable_sqrt( double );
    double variable_sqrt( double, int&, int& );
    double variable_pow(  double );
    double variable_pow(  double, int&, int& );

    void   validationstrexpression();
    bool   bracecorrect(  int,    int );
    void   bracecorrectclose(     int,  char );

    void   coutkind( int, double );
    void   strnum_cout();
};

//-------------------------------------------

// Error handing
class errornooperands{};
class errornooperators{};
class errortwooperatorsinarow{};
class errorfactorial{};
class erroremptybraces{};
class errorbracecorrect{};
class errorseparatorcorrect{};
class divisionbyzero{};
class errorequalscorrect{};
class errorsqrtcorrect{};
class errorpowcorrect{};
class errordefault{};

//-------------------------------------------

void calculator_calculation();

//-------------------------------------------


